<template>
  <view class="page-container">
    <!-- 固定顶部区域 -->
    <view class="fixed-header">
      <swiper
        style="height: 400rpx"
        :autoplay="true"
        :interval="3000"
        indicator-dots
      >
        <swiper-item>
          <image
            mode="widthFix"
            src="../../static/images/yjs.jpg"
            style="width: 100%; height: 100%"
          ></image>
        </swiper-item>
      </swiper>

      <view class="nav">
        <view class="header">
          <view class="left">
            <view class="store-name">
              <view style="width: 90%" @click="selectHospital()">
                您当前所选择的医院：
                <text style="color: #0baf6c"
                  >{{ currentHospital.name || "选择院区" }}
                  <view class="iconfont iconarrow-right"></view
                ></text>
              </view>
              <view class="member-qr-code" @click="scanToGetAddress">
                <image
                  src="/static/images/scan-icon.png"
                  class="qr-code-icon"
                ></image>
              </view>
            </view>
          </view>
        </view>
      </view>

      <!-- 商户tab -->
      <view class="shop-tabs" v-if="shops.length > 0">
        <view
          class="shop-tab"
          v-for="(shop, index) in shops"
          :key="index"
          :class="{ active: currentShopIndex === index }"
          @tap="handleShopTabChange(index)"
        >
          <text>{{ shop.name }}</text>
        </view>
      </view>

      <view style="height: 60rpx" v-if="store.notice">
        <uni-notice-bar
          style="margin-top: 14upx"
          color="#5A5B5C;"
          backgroundColor=""
          scrollable="true"
          single="true"
          :text="store.notice"
        ></uni-notice-bar>
      </view>
    </view>

    <!-- 可滚动内容区域 -->

    <view class="content-container">
      <!-- 左侧分类 -->
      <scroll-view
        class="menus"
        :scroll-into-view="menuScrollIntoView"
        scroll-with-animation
        scroll-y
      >
        <view class="wrapper" style="padding-bottom: 150rpx">
          <view
            class="menu"
            :id="`menu-${item.id}`"
            :class="{ current: item.id === currentCateId }"
            v-for="(item, index) in goodsCateList"
            :key="index"
            @tap="handleMenuTap(item.id)"
          >
            <view
              style="display: flex; flex-direction: column; align-items: center"
            >
              <image
                mode="aspectFill"
                :src="item.icon"
                style="width: 40rpx; height: 40rpx; margin-bottom: 10rpx"
              ></image>
              <text>{{ item.name }}</text>
            </view>
          </view>
        </view>
      </scroll-view>

      <!-- 右侧商品 -->
      <scroll-view
        class="goods"
        scroll-with-animation
        scroll-y
        @scroll="handleGoodsScroll"
        @scrolltolower="handleScrollToLower"
        :scroll-top="goodsScrollTop"
        :scroll-into-view="goodsScrollIntoView"
      >
        <view class="wrapper">
          <view
            v-for="(category, cateIndex) in allGoods"
            :key="cateIndex"
            :id="`cate-${category.cateId}`"
          >
            <!-- <view class="category-title">{{ category.cateName }}</view> -->
            <view class="goods-container">
              <view
                class="goods-item"
                style="
                  display: flex;
                  padding: 20rpx;
                  border-bottom: 1px solid #f5f5f5;
                  align-items: center;
                "
                v-for="(item, index) in category.goodsList"
                :key="index"
              >
                <view
                  class="goods-image"
                  style="
                    width: 160rpx;
                    height: 160rpx;
                    margin-right: 20rpx;
                    flex-shrink: 0;
                  "
                >
                  <image
                    mode="aspectFill"
                    :src="item.main_image"
                    style="width: 100%; height: 100%; border-radius: 8rpx"
                  ></image>
                </view>
                <view
                  class="goods-info"
                  style="
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    justify-content: space-between;
                    height: 165rpx;
                  "
                >
                  <text
                    class="name"
                    style="
                      font-size: 28rpx;
                      font-weight: bold;
                      line-height: 1.3;
                      display: -webkit-box;
                      -webkit-line-clamp: 2;
                      -webkit-box-orient: vertical;
                      overflow: hidden;
                    "
                    >{{ item.name }}</text
                  >
                  <text class="tips" style="font-size: 22rpx; color: #999"
                    >剩余：{{ item.stock || 0 }}份</text
                  >
                  <view
                    style="
                      display: flex;
                      justify-content: space-between;
                      align-items: center;
                    "
                  >
                    <text
                      class="price"
                      style="
                        font-size: 28rpx;
                        color: #1a9364;
                        font-weight: bold;
                      "
                      >￥{{ item.price }}</text
                    >
                    <view
                      class="btn-group"
                      v-if="!item.use_spec && item.stock > 0"
                    >
                      <button
                        type="primary"
                        v-show="goodCartNum(item.id)"
                        class="btn reduce_btn"
                        size="mini"
                        hover-class="none"
                        @tap="handleReduceFromCart(item, item)"
                      >
                        <view class="iconfont iconsami-select"></view>
                      </button>
                      <view class="number" v-show="goodCartNum(item.id)">
                        {{ goodCartNum(item.id) }}
                      </view>
                      <button
                        type="primary"
                        class="btn add_btn"
                        size="min"
                        hover-class="none"
                        @tap="handleAddToCart(item, item, 1)"
                      >
                        <view class="iconfont iconadd-select"></view>
                      </button>
                    </view>
                    <view
                      v-if="item.stock == 0"
                      style="color: #999; font-size: 24rpx"
                      >已售罄</view
                    >
                  </view>
                </view>
              </view>
            </view>
          </view>

          <!-- 加载更多提示 -->
          <view class="loading-more" v-if="isLoadingMore">加载中...</view>
          <view class="loading-more" v-if="!hasMore && allGoods.length > 0"
            >已加载全部商品</view
          >
        </view>
      </scroll-view>
    </view>

    <!-- 购物结算浮动条 -->
    <view class="cart-box">
      <view>
        <image
          src="/static/images/menu/cart.png"
          class="cart-img"
          @tap="openCartPopup"
        ></image>
        <view class="mark">
          <view class="tag">{{
            getCartGoodsNumber || (table.products ? table.products.length : 0)
          }}</view>
        </view>
      </view>
      <view class="price"
        >￥{{ formatPrice(getCartGoodsPrice || getTableGoodsPrice) }}</view
      >
      <button
        type="primary"
        class="pay-btn"
        @tap="toPay"
        :disabled="disabledPay"
      >
        {{ disabledPay ? `差${formatPrice(spread)}元起送` : "  去结算" }}
      </button>
    </view>

    <!-- 通知弹窗 -->
    <modal
      :show="noticeModalVisible"
      class="notice-modal"
      color="#5A5B5C"
      width="85%"
      custom
      radius="16rpx"
      padding="0"
    >
      <view
        class="notice-header"
        style="
          position: relative;
          background-image: url('https://www.qidzn.com/static/wechat_pic/notice.jpeg');
          background-size: 120% 100%;
          height: 300rpx;
          border-top-left-radius: 16rpx;
          border-top-right-radius: 16rpx;
          padding: 0;
        "
      >
        <view class="notice-close-btn" @tap="closeNoticeModal">
          <image
            src="/static/images/menu/close.png"
            style="width: 80rpx; height: 80rpx"
            mode="widthFix"
          ></image>
        </view>
      </view>

      <view class="notice-content">
        <view class="notice-date">
          {{ noticeData.title }}
        </view>
        <view class="notice-text">
          {{ filterHtmlTags(noticeData.content) }}
        </view>
      </view>
    </modal>

    <!-- 医院选择popup -->
    <popup-layer
      direction="top"
      :show-pop="hospitalPopupVisible"
      class="hospital-popup"
    >
      <template slot="content">
        <view class="hospital-list">
          <view
            class="hospital-item"
            v-for="(hospital, index) in hospitals"
            :key="index"
            @tap="handleSelectHospital(index)"
          >
            <text>{{ hospital.name }} (距离: {{ hospital.distance }}km)</text>
          </view>
        </view>
      </template>
    </popup-layer>

    <u-toast ref="uToast"></u-toast>

    <popup-layer
      direction="top"
      :show-pop="cartPopupVisible"
      class="cart-popup"
    >
      <template slot="content">
        <view class="top">
          <text @tap="handleCartClear">清空</text>
        </view>
        <scroll-view class="cart-list" scroll-y>
          <view class="wrapper">
            <view class="item" v-for="(item, index) in cart" :key="index">
              <view class="left">
                <view class="name">{{ item.name }}</view>
                <view class="props">{{ item.props_text }}</view>
              </view>
              <view class="center">
                <text>￥{{ item.sales_price }}</text>
              </view>
              <view class="right">
                <button
                  type="default"
                  plain
                  size="mini"
                  class="btn"
                  hover-class="none"
                  @tap="handleCartItemReduce(index)"
                >
                  <view class="iconfont iconsami-select"></view>
                </button>
                <view class="number">{{ item.number }}</view>
                <button
                  type="primary"
                  class="btn"
                  size="min"
                  hover-class="none"
                  @tap="handleCartItemAdd(index)"
                >
                  <view class="iconfont iconadd-select"></view>
                </button>
              </view>
            </view>
            <view
              class="item"
              v-if="orderType == 'takeout' && store.packing_fee"
            >
              <view class="left">
                <view class="name">包装费</view>
              </view>
              <view class="center">
                <text>￥{{ parseFloat(store.packing_fee) }}</text>
              </view>
              <view class="right invisible">
                <button
                  type="default"
                  plain
                  size="mini"
                  class="btn"
                  hover-class="none"
                >
                  <view class="iconfont iconsami-select"></view>
                </button>
                <view class="number">1</view>
                <button
                  type="primary"
                  class="btn"
                  size="min"
                  hover-class="none"
                >
                  <view class="iconfont iconadd-select"></view>
                </button>
              </view>
            </view>
          </view>
        </scroll-view>
      </template>
    </popup-layer>
  </view>
</template>

<script>
import modal from "@/components/modal/modal";
import popupLayer from "@/components/popup-layer/popup-layer";
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
import uniNoticeBar from "@/components/uni-notice-bar/uni-notice-bar.vue";
import ourLoading from "@/components/our-loading/our-loading.vue";

export default {
  components: {
    modal,
    popupLayer,
    uniNoticeBar,
    ourLoading,
  },
  data() {
    return {
      noticeModalVisible: false,
      noticeData: {},
      listAds: [{}],
      goodsCateList: [],
      allGoods: [], 
      currentCategoryIndex: 0, 
      loadingCateIndex: 0, 
      ads: [],
      loading: true,
      pageSize: 10,
      hasMore: true,
      isLoadingMore: false,
      currentCateId: null,
      menuScrollIntoView: "",
      cart: [],
      goodDetailModalVisible: false,
      good: {},
      category: {},
      cartPopupVisible: false,
      sizeCalcState: false,
      categoryPositions: [], 
      hospitals: [],
      currentHospital: {},
      shops: [],
      currentShopIndex: 0,
      hospitalPopupVisible: false,
      scannedAddress: "", 
      hasLoaded: false, 
      goodsScrollTop: 0,
      goodsScrollIntoView: "",
      scrollTimer: null,
      lastScrollTop: 0,
      isManualScroll: false, 
      hasHospitalIdFromScan: false, 
    };
  },

  onLoad(options) {
    if (options && options.q) {
      const url = decodeURIComponent(options.q);
      if (url.includes("?")) {
        const urlParts = url.split("?");
        if (urlParts.length > 1) {
          const params = urlParts[1].split("&");
          let bedParam = "";
          let hospitalId = null;
          for (const param of params) {
            if (param.startsWith("bed=")) {
              bedParam = decodeURIComponent(param.substring(4));
            } else if (param.startsWith("hospital_id=")) {
              hospitalId = param.substring(12);
            } else if (param.startsWith("H=")) {
              hospitalId = param.substring(2);
            }
          }
          if (hospitalId === null) {
            hospitalId = "1";
          }
          if (hospitalId || bedParam) {
            // 如果有医院ID，设置标记不进行距离定位
            this.hasHospitalIdFromScan = !!hospitalId;
            this.handleUrlParams(hospitalId, bedParam);
          } else {
            this.$u.toast("参数解析失败，请检查二维码");
          }
        }
      }
    }
  },
  onHide() {
    this.sizeCalcState = false;
  },
  onShow() {
    // 如果没有当前医院信息，并且不是通过扫码获取的医院ID，才进行距离定位
    if (!this.currentHospital.name && !this.hasHospitalIdFromScan) {
      this.init();
    } else {
      this.refreshCart();
    }
    if (!this.hasLoaded) {
      this.fetchNotice();
      this.hasLoaded = true;
    }
  },
  computed: {
    ...mapState(["orderType", "address", "store", "table", "location"]),
    ...mapGetters(["isLogin"]),
    goodCartNum() {
      return (id) =>
        this.cart.reduce((acc, cur) => {
          if (cur.id === id) {
            return (acc += cur.number);
          }
          return acc;
        }, 0);
    },
    menuCartNum() {
      return (id) =>
        this.cart.reduce((acc, cur) => {
          if (cur.cate_id === id) {
            return (acc += cur.number);
          }
          return acc;
        }, 0);
    },
    getCartGoodsNumber() {
      return this.cart.reduce((acc, cur) => acc + cur.number, 0);
    },
    getCartGoodsPrice() {
      let price = this.cart.reduce((acc, cur) => {
        const itemPrice = parseFloat(cur.sales_price) || 0;
        return acc + itemPrice * cur.number;
      }, 0);
      return price.toFixed(2);
    },
    getTableGoodsPrice() {
      if (!this.table || !this.table.products) {
        return "0.00";
      }
      let price = this.table.products.reduce((acc, cur) => {
        const itemPrice = parseFloat(cur.price) || 0;
        return acc + itemPrice * cur.number;
      }, 0);
      return price.toFixed(2);
    },
    disabledPay() {
      // 使用takeaway_price字段，且最低价设为0
      return this.orderType == "takeout" &&
        parseFloat(this.getCartGoodsPrice) < 0
        ? true
        : false;
    },
    spread() {
      if (this.orderType != "takeout") return 0;
      // 外卖最低价设为0，所以差额始终为0
      return "0.00";
    },
  },
  methods: {
    ...mapMutations([
      "SET_ORDER_TYPE",
      "SET_STORE",
      "SET_LOCATION",
      "SET_TABLE",
    ]),
    ...mapActions(["getStore"]),
    formatPrice(price) {
      const num = parseFloat(price);
      return isNaN(num) ? "0.00" : num.toFixed(2);
    },
    filterHtmlTags(html) {
      if (!html) return "";
      return html.replace(/<[^>]+>/g, "").trim();
    },
    in_array(search, array) {
      for (var i in array) {
        if (array[i] == search) {
          return true;
        }
      }
      return false;
    },
    // 获取最新通知
    async fetchNotice() {
      try {
        const res = await this.$u.api.getNotice();
        if (res && Object.keys(res).length > 0) {
          this.noticeData = res;
          this.noticeModalVisible = true;
        } else {
          this.noticeModalVisible = false;
        }
      } catch (error) {
        this.noticeModalVisible = false;
      }
    },
    // 关闭通知弹窗
    closeNoticeModal() {
      this.noticeModalVisible = false;
    },
    async init() {
      this.loading = true;
      let res = {
        latitude: 31.356707,
        longitude: 118.364493,
      };
      let error = false;
      try {
        [error, res] = await uni.getLocation({
          type: "wgs84",
        });
      } catch (e) {
        console.log("获取定位失败");
      }
      if (error) {
        // this.$refs.uToast.show({
        //     title: '获取位置失败，请检查是否开启相关权限',
        //     type: 'error'
        // });
      }
      if (res) {
        this.SET_LOCATION(res);
        let hospitals = await this.$u.api.hospitalNearby({
          lat: res.latitude,
          lng: res.longitude,
        });
        console.log("医院列表", hospitals);
        if (hospitals && hospitals.length > 0) {
          this.hospitals = hospitals;
          this.currentHospital = hospitals[0]; // 默认第一个
          await this.loadShops(this.currentHospital.id);
        }
        this.loading = false;
        uni.stopPullDownRefresh();
      }
    },
    async handleUrlParams(hospitalId, bedParam) {
      console.log("URL参数解析结果:", {hospitalId, bedParam});
      
      // 如果hospital_id存在，则直接切换医院
      if (hospitalId) {
        // 如果hospitals数组为空，需要先获取医院列表
        if (!this.hospitals || this.hospitals.length === 0) {
          await this.initHospitals();
        }
        
        const targetHospital = this.hospitals.find((h) => h.id == hospitalId);
        if (targetHospital) {
          this.currentHospital = targetHospital;
          await this.loadShops(hospitalId);
          if (bedParam) {
            this.scannedAddress = bedParam;
            this.$u.toast(`已切换到${targetHospital.name}`);
          }
        } else {
          console.warn(`未找到ID为 ${hospitalId} 的医院`);
        }
      } else if (bedParam) {
        this.scannedAddress = bedParam;
      }
    },
    
    async initHospitals() {
      let res = {
        latitude: 31.356707,
        longitude: 118.364493
      };
      let error = false;
      try {
        [error, res] = await uni.getLocation({
          type: 'wgs84'
        });
      } catch (e) {
        console.log('获取定位失败')
      }
      
      if (res) {
        this.SET_LOCATION(res);
        let hospitals = await this.$u.api.hospitalNearby({
          lat: res.latitude,
          lng: res.longitude
        });
        console.log('医院列表', hospitals);
        if (hospitals && hospitals.length > 0) {
          this.hospitals = hospitals;
        }
      }
    },

    scanToGetAddress() {
      this.address.address_id = "";
      uni.scanCode({
        onlyFromCamera: true,
        scanType: ["barCode", "qrCode"],
        success: (res) => {
          try {
            let bedParam = "";
            let hospitalId = null;
            if (res.result.includes("?")) {
              const urlParts = res.result.split("?");
              if (urlParts.length > 1) {
                const params = urlParts[1].split("&");
                for (const param of params) {
                  if (param.startsWith("bed=")) {
                    bedParam = decodeURIComponent(param.substring(4));
                  } else if (param.startsWith("hospital_id=")) {
                    hospitalId = param.substring(12);
                  } else if (param.startsWith("H=")) {
                    hospitalId = param.substring(2);
                  }
                }
              }
            }
            // 添加判断：如果没有找到hospital_id，则默认设置为'1'
            if (hospitalId === null) {
              hospitalId = "1";
            }
            console.log("扫描到的地址:", bedParam);
            console.log("扫描到的医院:", hospitalId);

            // 如果hospital_id存在且与当前选择不同，则切换医院
            if (hospitalId && this.currentHospital.id != hospitalId) {
              const targetHospital = this.hospitals.find(
                (h) => h.id == hospitalId
              );
              if (targetHospital) {
                this.currentHospital = targetHospital;
                this.loadShops(hospitalId).then(() => {
                  if (bedParam) {
                    this.scannedAddress = bedParam;
                    this.$u.toast(`已切换到${targetHospital.name}`);
                  }
                });
              }
            } else if (bedParam) {
              this.scannedAddress = bedParam;
            }
          } catch (e) {
            console.error("Scan error:", e);
          }
        },
        fail: () => {
          this.$u.toast("扫码失败，请重试");
        },
      });
    },
    async loadShops(hospital_id) {
      let shops = await this.$u.api.getShopList({
        hospital_id: hospital_id,
      });
      console.log("商户列表", shops.list);
      if (shops && shops.list.length > 0) {
        this.shops = shops.list;
        this.currentShopIndex = 0;
        this.SET_STORE(shops.list[0]);
        this.allGoods = []; // 清空所有商品
        this.goodsCateList = [];

        let goodsCate = await this.$u.api.menuGoodsCate({
          merchant_id: shops.list[0].id,
        });
        if (goodsCate && goodsCate.list) {
          this.goodsCateList = goodsCate.list;
          this.refreshCart();

          // 初始化分类商品结构
          this.allGoods = this.goodsCateList.map((cate) => ({
            cateId: cate.id,
            cateName: cate.name,
            goodsList: [],
            hasMore: true,
            page: 0,
          }));

          if (this.goodsCateList.length > 0) {
            this.currentCateId = this.goodsCateList[0].id;
            this.currentCategoryIndex = 0;
            await this.loadCategoryGoods(0); // 加载第一个分类的商品
          }
        }
        this.sizeCalcState = false;
        this.calcCategoryPositions();
      } else {
        this.$refs.uToast.show({
          title: "该医院暂无商户",
          type: "error",
        });
        this.shops = [];
        this.allGoods = [];
        this.goodsCateList = [];
        this.currentShopIndex = 0;
        this.SET_STORE({});
      }
    },
    selectHospital() {
      this.hospitalPopupVisible = false;
      this.$nextTick(() => {
        this.hospitalPopupVisible = true;
      });
    },
    handleSelectHospital(index) {
      this.currentHospital = this.hospitals[index];
      this.hospitalPopupVisible = false;
      this.loadShops(this.currentHospital.id);
    },

    async handleShopTabChange(index) {
      const currentShopId = this.shops[this.currentShopIndex]?.id;
      const hasOtherShopGoods = this.cart.some(
        (item) =>
          item.cate_id &&
          !this.goodsCateList.some((cate) => cate.id === item.cate_id)
      );
      if (hasOtherShopGoods) {
        const [confirm] = await new Promise((resolve) => {
          uni.showModal({
            title: "温馨提示",
            content: "您有其他商户的商品未结算，是否清空购物车?",
            success: ({ confirm }) => resolve([confirm]),
          });
        });
        if (!confirm) return;
        this.cart = [];
        uni.setStorageSync("cart", JSON.stringify(this.cart));
      }

      this.currentShopIndex = index;
      this.SET_STORE(this.shops[index]);
      uni.showLoading({ title: "加载中..." });

      try {
        this.allGoods = [];
        this.goodsCateList = [];

        let goodsCate = await this.$u.api.menuGoodsCate({
          merchant_id: this.shops[index].id,
        });
        this.goodsCateList = goodsCate.list || [];
        this.refreshCart();

        this.allGoods = this.goodsCateList.map((cate) => ({
          cateId: cate.id,
          cateName: cate.name,
          goodsList: [],
          hasMore: true,
          page: 0,
        }));

        if (this.goodsCateList.length > 0) {
          this.currentCateId = this.goodsCateList[0].id;
          this.currentCategoryIndex = 0;
          await this.loadCategoryGoods(0); // 加载第一个分类的商品
        }
      } catch (e) {
        console.error("切换商户失败:", e);
        this.$refs.uToast.show({
          title: "加载失败，请重试",
          type: "error",
        });
      } finally {
        uni.hideLoading();
      }
    },
    refreshCart() {
      if (this.goodsCateList && this.goodsCateList.length > 0) {
        let goods = this.goodsCateList;
        this.cart = [];
        let cart = uni.getStorageSync("cart") || [];
        let tmpCart = [];
        if (cart) {
          for (let i in cart) {
            for (let ii in goods) {
              for (let iii in goods[ii].goods_list) {
                if (cart[i].id == goods[ii].goods_list[iii].id) {
                  tmpCart.push(cart[i]);
                }
              }
            }
          }
          this.cart = tmpCart;
          this.cartPopupVisible = false;
        }
      }
    },
    takout(force = false) {
      if (this.orderType == "takeout" && force == false) return;
      if (!this.isLogin) {
        uni.navigateTo({
          url: "/pages/components/pages/login/login",
        });
        return;
      } else {
        if (!this.address.hasOwnProperty("address") || force == true) {
          uni.navigateTo({
            url: "/pages/components/pages/address/address?is_choose=true",
          });
        } else {
          this.SET_ORDER_TYPE("takeout");
        }
      }
    },
    // 加载指定分类的商品
    async loadCategoryGoods(cateIndex) {
      if (cateIndex >= this.allGoods.length) return;

      const category = this.allGoods[cateIndex];
      if (!category.hasMore || this.isLoadingMore) return;

      this.isLoadingMore = true;
      this.loadingCateIndex = cateIndex;

      try {
        let goodsData = await this.$u.api.menuGoods({
          cate_id: category.cateId,
          page: category.page,
          pageSize: this.pageSize,
        });

        if (goodsData && goodsData.list && goodsData.list.length > 0) {
          if (category.page === 0) {
            this.allGoods[cateIndex].goodsList = goodsData.list;
          } else {
            this.allGoods[cateIndex].goodsList.push(...goodsData.list);
          }

          this.allGoods[cateIndex].hasMore =
            goodsData.list.length >= this.pageSize;
          this.allGoods[cateIndex].page = category.page + 1;
        } else {
          this.allGoods[cateIndex].hasMore = false;
        }

        // 计算分类位置信息
        this.$nextTick(() => {
          this.calcCategoryPositions();
        });
      } catch (e) {
        console.error(`加载分类 ${category.cateName} 商品失败:`, e);
        this.$refs.uToast.show({
          title: "加载商品失败，请重试",
          type: "error",
        });
      } finally {
        this.isLoadingMore = false;
      }
    },
    // 处理分类点击
    async handleMenuTap(cateId) {
      const cateIndex = this.goodsCateList.findIndex(
        (item) => item.id === cateId
      );
      if (cateIndex === -1) return;

      this.currentCateId = cateId;
      this.currentCategoryIndex = cateIndex;

      // 如果该分类没有加载过商品，则加载
      if (this.allGoods[cateIndex].goodsList.length === 0) {
        uni.showLoading({ title: "加载中..." });
        await this.loadCategoryGoods(cateIndex);
        uni.hideLoading();
      }

      // 滚动到对应的分类位置
      this.isManualScroll = true;
      this.goodsScrollIntoView = `cate-${cateId}`;

      // 重置自动滚动标记
      setTimeout(() => {
        this.isManualScroll = false;
      }, 500);
    },
    // 处理商品滚动
    handleGoodsScroll({ detail }) {
      if (this.isManualScroll) return;

      const { scrollTop } = detail;
      this.lastScrollTop = scrollTop;

      if (!this.sizeCalcState) {
        this.calcCategoryPositions();
        return;
      }

      // 防抖处理
      if (this.scrollTimer) {
        clearTimeout(this.scrollTimer);
      }

      this.scrollTimer = setTimeout(() => {
        // 找到当前可见的分类
        for (let i = this.categoryPositions.length - 1; i >= 0; i--) {
          if (scrollTop >= this.categoryPositions[i].top - 50) {
            if (this.currentCateId !== this.categoryPositions[i].cateId) {
              this.currentCateId = this.categoryPositions[i].cateId;
              this.currentCategoryIndex = this.goodsCateList.findIndex(
                (item) => item.id === this.categoryPositions[i].cateId
              );
              this.menuScrollIntoView = `menu-${this.currentCateId}`;
            }
            break;
          }
        }
      }, 100);
    },
    // 处理滚动到底部
    async handleScrollToLower() {
      console.log(111);
      // 先检查当前分类是否还有更多商品
      if (this.allGoods[this.currentCategoryIndex].hasMore) {
        await this.loadCategoryGoods(this.currentCategoryIndex);
      } else if (this.currentCategoryIndex < this.allGoods.length - 1) {
        // 当前分类没有更多，自动加载下一个分类
        this.currentCategoryIndex++;
        this.currentCateId = this.allGoods[this.currentCategoryIndex].cateId;
        this.menuScrollIntoView = `menu-${this.currentCateId}`;

        // 如果下一个分类没有商品，则加载
        if (this.allGoods[this.currentCategoryIndex].goodsList.length === 0) {
          await this.loadCategoryGoods(this.currentCategoryIndex);
        }
      } else {
        // 所有分类都已加载完毕
        this.hasMore = false;
      }
    },
    // 计算分类位置
    calcCategoryPositions() {
      const query = uni.createSelectorQuery().in(this);
      this.categoryPositions = [];

      this.allGoods.forEach((category) => {
        if (category.goodsList.length > 0) {
          query
            .select(`#cate-${category.cateId}`)
            .boundingClientRect((res) => {
              if (res) {
                this.categoryPositions.push({
                  cateId: category.cateId,
                  top: res.top,
                });
              }
            })
            .exec();
        }
      });

      this.sizeCalcState = true;
    },
    handleAddToCart(cate, good, num) {
      const index = this.cart.findIndex((item) => {
        if (good.use_spec) {
          return (
            item.id === good.id &&
            item.props_text === this.getGoodSelectedProps(good)
          );
        } else {
          return item.id === good.id;
        }
      });
      if (index > -1) {
        this.cart[index].number += num;
      } else {
        this.cart.push({
          id: good.id,
          cate_id: cate.id,
          name: good.name,
          sales_price: parseFloat(good.price || good.sales_price || 0).toFixed(
            2
          ),
          number: num,
          image: good.main_image || good.image,
          use_property: good.use_spec,
          props_text: good.use_spec ? this.getGoodSelectedProps(good) : "",
        });
      }
      uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
    },
    handleReduceFromCart(item, good) {
      const index = this.cart.findIndex((item) => item.id === good.id);
      if (index > -1) {
        this.cart[index].number -= 1;
        if (this.cart[index].number <= 0) {
          this.cart.splice(index, 1);
        }
        uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
      }
    },
    showGoodDetailModal(item, good) {
      this.good = JSON.parse(
        JSON.stringify({
          ...good,
          number: 1,
        })
      );
      this.category = JSON.parse(JSON.stringify(item));
      this.goodDetailModalVisible = true;
      this.changePropertyDefault(0, 0);
    },
    closeGoodDetailModal() {
      this.goodDetailModalVisible = false;
      this.category = {};
      this.good = {};
    },
    changePropertyDefault(index, key) {
      if (!this.good.specList[index] || !this.good.specList[index].child[key]) {
        return;
      }
      this.good.specList[index].default = this.good.specList[index].child[key];
      this.good.number = 1;
      let specSelectedName = [];
      for (let item of this.good.specList) {
        if (item.default != "") {
          specSelectedName.push(item.default);
        }
      }
      for (let item of this.good.specTableList) {
        if (item.value.join(" ") == specSelectedName.join(" ")) {
          this.good.market_price = parseFloat(item.market_price).toFixed(2);
          this.good.sales_price = parseFloat(item.sales_price).toFixed(2);
          this.good.stock = item.stock;
          this.good.image = item.image ? item.image : this.good.image;
        }
      }
    },
    getGoodSelectedProps(good, type = "text") {
      if (good.use_spec) {
        let props = [];
        good.specList.forEach((values) => {
          if (type === "text") {
            props.push(values.default);
          }
        });
        return type === "text" ? props.join(",") : props;
      }
      return "";
    },
    handlePropertyAdd() {
      this.good.number += 1;
    },
    handlePropertyReduce() {
      if (this.good.number === 1) return;
      this.good.number -= 1;
    },
    handleAddToCartInModal() {
      if (this.good.stock <= 0) {
        this.$u.toast("商品库存不足");
        return;
      }
      this.handleAddToCart(this.category, this.good, this.good.number);
      this.closeGoodDetailModal();
    },
    openCartPopup() {
      this.cartPopupVisible = !this.cartPopupVisible;
    },
    handleCartClear() {
      uni.showModal({
        title: "提示",
        content: "确定清空购物车么",
        success: ({ confirm }) => {
          if (confirm) {
            this.cartPopupVisible = false;
            this.cart = [];
            uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
          }
        },
      });
    },
    handleCartItemAdd(index) {
      this.cart[index].number += 1;
      uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
    },
    handleCartItemReduce(index) {
      if (this.cart[index].number === 1) {
        this.cart.splice(index, 1);
      } else {
        this.cart[index].number -= 1;
      }
      if (!this.cart.length) {
        this.cartPopupVisible = false;
      }
      uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
    },
    toPay() {
      if (this.cart.length === 0) {
        this.$u.toast("您还未选中商品");
        return;
      }
      if (this.scannedAddress) {
        this.$store.commit("SET_ADDRESS", {
          ...this.address,
          address_detail: this.scannedAddress,
        });
      }

      const merchantId = this.shops[this.currentShopIndex]?.id;
      if (!merchantId) {
        this.$u.toast("商户信息获取失败");
        return;
      }

      if (!this.isLogin) {
        uni.navigateTo({
          url: "/pages/components/pages/login/login",
        });
        return;
      } else {
        if (this.store.status == 0) {
          this.$u.toast("不在店铺营业时间内");
          return;
        }
        if (
          this.orderType == "takeout" &&
          this.store.distance < this.store.far
        ) {
          this.$u.toast("选中的地址不在配送范围");
          return;
        }
        uni.showLoading({
          title: "加载中",
        });
        uni.setStorageSync("cart", JSON.parse(JSON.stringify(this.cart)));
        uni.setStorageSync("table", JSON.parse(JSON.stringify(this.table)));
        uni.setStorageSync("store", JSON.parse(JSON.stringify(this.store)));
        if (this.table.switch == 1) {
          uni.navigateTo({
            url: "/pages/components/pages/pay/payAfter",
          });
        } else {
          uni.navigateTo({
            url: `/pages/components/pages/pay/pay?address_detail=${encodeURIComponent(
              this.scannedAddress || ""
            )}`,
          });
        }
      }
      uni.hideLoading();
    },
  },
};
</script>

<style lang="scss" scoped>
@import "~@/pages/index/index.scss";

// .page-container {
//     display: flex;
//     flex-direction: column;
//     min-height: 100vh;
// }

/* 固定顶部区域样式 */
.fixed-header {
  position: sticky;
  top: 0;
  z-index: 97;
  background-color: #fff;
}

/* 可滚动内容区域 */
.scrollable-content {
  flex: 1;
  overflow: hidden;
  padding-bottom: 120rpx;
}

.content-container {
  display: flex;
  overflow: hidden;
  height: 100%;
}

.menus {
  width: 215rpx;
  height: calc(100vh - 600rpx);
  background-color: #f5f5f5;
  flex-shrink: 0;
}

.menu {
  padding: 20rpx 0;
  text-align: center;
  position: relative;
  &.current {
    background-color: #1a9364;
    font-weight: bold;
    color: #fff;
  }
}

.dot {
  position: absolute;
  right: 20rpx;
  top: 15rpx;
  background-color: #1a9364;
  color: white;
  border-radius: 50%;
  width: 30rpx;
  height: 30rpx;
  font-size: 20rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 右侧商品区域 */
.goods {
  flex: 1;
  height: calc(100vh - 700rpx); /* 根据顶部高度调整 */
  overflow-y: auto;
}

.category-title {
  font-size: 30rpx;
  // font-weight: bold;
  padding: 15rpx 20rpx;
  background-color: #f5f5f5;
  color: #666;
}

/* 商户tab样式 */
.shop-tabs {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  padding: 20rpx 20rpx;
  box-sizing: border-box;
  width: 100%;
}

.shop-tab {
  padding: 10rpx 20rpx;
  margin-right: 10rpx;
  border-radius: 20rpx;
  font-weight: bold;
  white-space: nowrap;
  &.active {
    color: #1a9364;
    border-color: #1a9364;
    text-decoration: underline;
    text-decoration-color: #1a9364;
    text-underline-offset: 8px;
    text-decoration-thickness: 2px;
  }
  &:not(.active) {
    color: #000;
  }
}

/* 医院选择弹窗 */
.hospital-popup {
  .hospital-list {
    padding: 20rpx;
  }
  .hospital-item {
    padding: 20rpx;
    border-bottom: 1px solid #eee;
  }
}

/* 商品样式补充 */
.good {
  &.backgroud-grey {
    background-color: #f9f9f9;
    opacity: 0.7;
  }
}

.price {
  color: #1a9364;
  font-weight: bold;
}

/* 购物车结算条样式 */
.cart-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15rpx 30rpx;
  background-color: #444;
  border-top: 1px solid #eee;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  width: 92%;
  margin: 0 auto;
  z-index: 97;
  height: 100rpx;
  box-sizing: border-box;

  .cart-img {
    width: 80rpx;
    height: 80rpx;
    position: relative;
    margin-top: 0rpx;
  }

  .mark {
    position: relative;
    .tag {
      position: absolute;
      top: -85rpx;
      right: -40rpx;
      background-color: #f72550;
      color: #fff;
      width: 30rpx;
      height: 30rpx;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 20rpx;
    }
  }

  .price {
    font-size: 38rpx;
    font-weight: bold;
    color: #fff;
  }

  .pay-btn {
    height: 70rpx;
    line-height: 70rpx;
    border-radius: 35rpx;
    background-color: #1a9364;
    color: #fff;
    font-size: 32rpx;
    font-weight: bold;
    padding: 0 45rpx;
    text-align: center;
  }
}

.cart-box.hidden {
  display: none;
}

/* 按钮组样式 */
.btn-group {
  display: flex;
  align-items: center;

  .btn {
    width: 50rpx;
    height: 50rpx;
    line-height: 50rpx;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #1a9364;
  }

  .number {
    width: 50rpx;
    text-align: center;
    font-size: 24rpx;
  }
}

.notice-modal {
  position: relative;
  padding: 0;
  .notice-content {
    white-space: pre-line;
    padding: 0 60rpx 60rpx 60rpx;
    font-size: 28rpx;
    line-height: 1.8;
    color: #555;
  }
  .notice-date {
    font-size: 32rpx;
    padding-bottom: 20rpx;
    font-weight: 500;
    color: #000;
    text-align: center;
  }
  .notice-text {
    font-size: 28rpx;
    line-height: 1.8;
    color: #555;
    white-space: pre-line;
    text-align: left;
  }
  .notice-close-btn {
    position: absolute;
    top: 20rpx;
    right: 10rpx;
    width: 120rpx;
    height: 100rpx;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.member-qr-code {
  width: 9%;
}

.qr-code-icon {
  width: 60rpx;
  height: 60rpx;
  margin-top: 20rpx;
}

/* 加载更多提示 */
.loading-more {
  text-align: center;
  padding: 20rpx;
  color: #999;
  font-size: 26rpx;
}

.nav {
  width: 100%;
  height: 100rpx;
  display: flex;
  flex-direction: column;
}

.nav .header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx;
  background-color: #ffffff;
  height: 100rpx;
}
</style>
